// SistemaAlertas.cc
// author: CASO-04

#include "TcpListener.h"
#include "Dsm.h"

#define BUFFER_SIZE 1024

void usage()
{
	cout << "Usage: SistemaAlertas <puerto-servidor-nombres> <nombre-servidor-memoria> <ubicacion> <catastrofe>" << endl;
	exit(1);
}


int main(int argc, char** argv)
{

        if (argc != 5)
        {
                usage();
        }

        // Hacer lookup dsm.deusto.es
        PracticaCaso::DsmDriver * driver = new PracticaCaso::DsmDriver("127.0.0.1", atoi(argv[1]), argv[2]);
        PracticaCaso::DsmData data1, data2;

        // El 1er proceso reserva la memoria
		char vdonde[10];
		char vque[10];
		
		int i;
		for (i = 0; argv[3][i] != '\0'; ++i)
		{
			vdonde[i] = argv[3][i];
		}
		vdonde[i] = '\0';
		for (i = 0; argv[4][i] != '\0'; ++i)
		{
			vque[i] = argv[4][i];
		}
		vque[i] = '\0';


        bool alertaExternaActivada = false, alertaLocalActivada = false;
        while (!alertaLocalActivada)
		{
	        try
	        {
	            data1 = driver->dsm_get("QUE");
	            data2 = driver->dsm_get("DONDE");
	            alertaExternaActivada = true;
	        }
	        catch (DsmException dsme)
	        {
	                cerr << "Esperando alerta." << endl;
	        }
            
            
			if(!alertaExternaActivada)
			{
        		cerr << "Buscando alertas locales... " << endl;
                // Decidir si mando yo una alerta
    			srand(time(NULL));
                int randNumber = (int)rand()%20; // Numbers between 0 and 60
                if (randNumber == 0)
                {
                    // Escribir alerta
                    try
                    {
                            driver->dsm_malloc("DONDE", sizeof(vdonde));
                            driver->dsm_malloc("QUE", sizeof(vque));
                    }
                    catch (DsmException dsme)
                    {
                            cerr << "La memoria ya estaba reservada." << endl;
                    }
                   
                    driver->dsm_put("DONDE", (void *)vdonde, sizeof(vdonde));
                    driver->dsm_put("QUE", (void *)vque, sizeof(vque));
                   
                    // Comunicar alerta
					cout << "Esta localización (\"" << vdonde << "\") ha enviado un aviso (por \"" << vque << "\")." << endl;
                       
                    // Salir del bloque
                    alertaLocalActivada = true;
			    }
			    else
			    {
			            cerr << "No hay ninguna alerta local." << endl;
			    }
          	}
          	
          	if (alertaExternaActivada)
		    {              		
		            // Mostrar alerta detectada
		            string s1 = "";
		            for(int i = 0; i<data1.size; i++)
		                    {
		                            s1 += ((char *)(data1.addr))[i];
		                            if ((((char *)(data1.addr))[i]) == '\0')
		                                    break;
		                    }
		            string s2 = "";
		            for(int i = 0; i<data2.size; i++)
		                    {
		                            s2 += ((char *)(data2.addr))[i];
		                            if ((((char *)(data2.addr))[i]) == '\0')
		                                    break;
		                    }
		           
					cout << "Alerta detectada en la LOCALIZACION \"" << s2 << "\", AVISO por \"" << s1 << "\"" << endl;
					alertaExternaActivada = false;
		    }
          	
            // Esperar 1 seg
            sleep(1);
        }
       
        
        // if (alertaLocalActivada)
        // Esperar para liberar la memoria
        cout << "Esperando 2 segundos para liberar la memoria y terminar." << endl;
        sleep(2);
        driver->dsm_free("QUE");
        driver->dsm_free("DONDE");
        cout << "Sleeping for a second before finishing ..." << endl;
        sleep(1);
        exit(0); //TODO probar después del delete
        delete driver;
}
//TODO probar 3 procesos
